package es.gesfutbol.web;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.ui.ModelMap;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MultiActionController;

import es.gesfutbol.dao.IEquipDao;
import es.gesfutbol.dao.IEquipEnLligaDao;
import es.gesfutbol.dao.IJornadaDao;
import es.gesfutbol.dao.ILligaDao;
import es.gesfutbol.dao.IPartitDao;
import es.gesfutbol.dao.IPenyaDao;
import es.gesfutbol.dao.IPercentatgeDao;
import es.gesfutbol.dao.IUtilsDao;
import es.gesfutbol.domini.implementacio.Equip;
import es.gesfutbol.domini.implementacio.EquipEnLliga;
import es.gesfutbol.domini.implementacio.Jornada;
import es.gesfutbol.domini.implementacio.Lliga;
import es.gesfutbol.domini.implementacio.Partit;
import es.gesfutbol.domini.implementacio.Penya;
import es.gesfutbol.domini.implementacio.Percentatge;
import es.gesfutbol.domini.implementacio.Utils;
import es.gesfutbol.util.OrdenaEquipsEnLligaPerPuntuacio;

public class EstadistiquesController extends MultiActionController{
	
	private static final String ID_PENYA_SESSION = "idDePenya";
	private String CLASSIFICACIO = "Classificacio";
	private String ENFRONTAMENTS_ANTERIORS = "EnfrontamentsAnteriors";
	private String LOCAL = "JugaComALocal";
	private String ULTIMS_RESULTATS = "UltimsResultatsObtinguts";
	
	private IEquipDao equipDao;
	private IPenyaDao penyaDao;
	private IEquipEnLligaDao equipEnLligaDao;
	private IUtilsDao utilsDao;
	private ILligaDao lligaDao;
	private IPartitDao partitDao;
	private IJornadaDao jornadaDao;
	private IPercentatgeDao percentatgeDao;

	public IEquipDao getEquipDao() {
		return equipDao;
	}

	public void setEquipDao(IEquipDao equipDao) {
		this.equipDao = equipDao;
	}

	public IEquipEnLligaDao getEquipEnLligaDao() {
		return equipEnLligaDao;
	}

	public void setEquipEnLligaDao(IEquipEnLligaDao equipEnLligaDao) {
		this.equipEnLligaDao = equipEnLligaDao;
	}

	public IUtilsDao getUtilsDao() {
		return utilsDao;
	}

	public void setUtilsDao(IUtilsDao utilsDao) {
		this.utilsDao = utilsDao;
	}

	public ILligaDao getLligaDao() {
		return lligaDao;
	}

	public void setLligaDao(ILligaDao lligaDao) {
		this.lligaDao = lligaDao;
	}

	public IPartitDao getPartitDao() {
		return partitDao;
	}

	public void setPartitDao(IPartitDao partitDao) {
		this.partitDao = partitDao;
	}

	public IJornadaDao getJornadaDao() {
		return jornadaDao;
	}

	public void setJornadaDao(IJornadaDao jornadaDao) {
		this.jornadaDao = jornadaDao;
	}

	public IPenyaDao getPenyaDao() {
		return penyaDao;
	}

	public void setPenyaDao(IPenyaDao penyaDao) {
		this.penyaDao = penyaDao;
	}
	
	public IPercentatgeDao getPercentatgeDao() {
		return percentatgeDao;
	}

	public void setPercentatgeDao(IPercentatgeDao percentatgeDao) {
		this.percentatgeDao = percentatgeDao;
	}

	public ModelAndView init(HttpServletRequest request,
			HttpServletResponse response) throws Exception {

				String sLocal = request.getParameter("local");
				String sVisitant = request.getParameter("visitant");
				
				Equip equipLocal = equipDao.findByNom(sLocal);
				Equip equipVisitant = equipDao.findByNom(sVisitant);
				
				Utils utils = utilsDao.findById("temporada");
				String temporada = utils.getValor();
				
				List<Lliga> lligues = lligaDao.findLliguesPerTemporada(temporada);
				
				Lliga lligaEquipLocal = new Lliga();
				Lliga lligaEquipVisitant = new Lliga();
				Iterator<Lliga> itLliga = lligues.iterator();
				while(itLliga.hasNext()){
					Lliga lliga = itLliga.next();
					if(equipEnLligaDao.findEquipEnLligaByEquipILliga(equipLocal.getIdEquip(), 
							lliga.getIdLliga()) != null){
						lligaEquipLocal = lliga;
					}
					if(equipEnLligaDao.findEquipEnLligaByEquipILliga(equipVisitant.getIdEquip(), 
							lliga.getIdLliga()) != null){
						lligaEquipVisitant = lliga;
					}
				}
				
				EquipEnLliga equipEnLligaLocal = equipEnLligaDao
					.findEquipEnLligaByEquipILligaDeproxy(equipLocal.getIdEquip(), 
							lligaEquipLocal.getIdLliga());
				
				EquipEnLliga equipEnLligaVisitant = equipEnLligaDao
					.findEquipEnLligaByEquipILligaDeproxy(equipVisitant.getIdEquip(), 
							lligaEquipLocal.getIdLliga());
								
				//Treiem el lloc que ocupen a la classificació
				List<EquipEnLliga> equipsEnLliga = equipEnLligaDao.findByIdLligaDeproxy(lligaEquipLocal.getIdLliga());
				Collections.sort(equipsEnLliga, new OrdenaEquipsEnLligaPerPuntuacio());
				Iterator<EquipEnLliga> itEELL = equipsEnLliga.iterator();
				int classLocal=0, classVisitant=0, posicio = 1;
				while(itEELL.hasNext()){
					EquipEnLliga equipEnLliga = itEELL.next();
					if(equipEnLligaLocal.getId().getEquip().getIdEquip() == equipEnLliga.getId().getEquip().getIdEquip()){
						classLocal = posicio;
					}
					if(equipEnLligaVisitant.getId().getEquip().getIdEquip() == equipEnLliga.getId().getEquip().getIdEquip()){
						classVisitant = posicio;
					}
					posicio++;
				}
				
				//Últims partits disputats
				List<Partit> partits = partitDao.findPartitByLocalIVisitant
						(equipLocal.getIdEquip(), equipVisitant.getIdEquip());
				
				List<Partit> partits2 = new ArrayList<Partit>();
				Iterator<Partit> itPartit = partits.iterator();
				while(itPartit.hasNext()){
					Partit partit = itPartit.next();
					partit = partitDao.deproxyJornadaLock(partit);
					Jornada jornada = partit.getJornada();
					jornada = jornadaDao.deproxyLliga(jornada);
					partit.setJornada(jornada);
					partits2.add(partit);					
				}
				Set<Partit> setPartits = new HashSet<Partit>(partits2);
				setPartits = partitDao.deproxylist(setPartits);
				
				//Busquem el partit de la temporada actual per saber la jornada a la que pertany,
				//la resta de partits seran els de les temporades anteriors i també cal guardar
				Iterator<Partit> itPartit2 = setPartits.iterator();
				Set<Partit> partitsAnteriors = new HashSet<Partit>();
				Partit partitActual = new Partit();
				
				while(itPartit2.hasNext()){
					Partit partit2 = itPartit2.next();
					Jornada j = partit2.getJornada();
					Lliga ll = j.getLliga();
					String temp = ll.getTemporada();
					if(temp.equals(temporada)){
						partitActual = partit2;
					}else{
						partitsAnteriors.add(partit2);
					}
				}
				
				//guardem la jornada actual i busquem totes les jornades
				//d'aquesta mateixa lliga
				Jornada jornadaActual = partitActual.getJornada();
				
				Set<Jornada> ultimesJornades = new HashSet<Jornada>();
				
				lligaEquipLocal = lligaDao.deproxy(lligaEquipLocal);
				Set<Jornada> jornadesLligaActual = lligaEquipLocal.getJornades();
				
				//guardem les últimes 5 jornades
				for(Jornada j1 : jornadesLligaActual){
					int jActual = jornadaActual.getNumero();					
					if(j1.getNumero() < jActual){
						ultimesJornades.add(j1);
					}
				}
				
				//insertem els partits
				Set<Jornada> ultimesJornadesDeproxy = new HashSet<Jornada>();
				if(!ultimesJornades.isEmpty()){
					for(Jornada j2 : ultimesJornades){
						ultimesJornadesDeproxy.add(jornadaDao.deproxy(j2));
					}
				}
				//guardem tots els partits en un set
				Set<Partit> partitsUltimesJornades = new HashSet<Partit>();
				for(Jornada j3 : ultimesJornadesDeproxy){
					Set<Partit> partitsJornada = new HashSet<Partit>();
					partitsJornada = j3.getPartits();
					for(Partit p1 : partitsJornada){
						partitsUltimesJornades.add(p1);
					}
				}
				Set<Partit> ultimsPartitsLocal = new HashSet<Partit>();
				Set<Partit> ultimsPartitsVisitant = new HashSet<Partit>();
				for(Partit p2 : partitsUltimesJornades){
					String nomPartit = p2.getNomPartit();
					if(nomPartit.contains(sLocal)){
						ultimsPartitsLocal.add(p2);
					}
					if(nomPartit.contains(sVisitant)){
						ultimsPartitsVisitant.add(p2);
					}
				}
								
				//PRONOSTIC RECOMANAT
				Penya penya = penyaDao.findById(Long.valueOf(request.getSession().getAttribute(ID_PENYA_SESSION).toString()));
				double prediccioLocal = 10;
				double prediccioVisitant = 10;
				
				//classificació
				Percentatge per1 = percentatgeDao.findByIdPenyaITipus(penya.getIdPenya(), CLASSIFICACIO);
				String sPerClass = per1.getValor();
				double perClass = Double.parseDouble(sPerClass);
				prediccioLocal = prediccioLocal-(classLocal*(perClass/100));
				prediccioVisitant = prediccioVisitant-(classVisitant*(perClass/100));				
				//enfrontaments anteriors
				@SuppressWarnings("unused")
				Percentatge per2 = percentatgeDao.findByIdPenyaITipus(penya.getIdPenya(), ENFRONTAMENTS_ANTERIORS);
				String sPerEnfAnt = per2.getValor();
				double perEnfAnt = Double.parseDouble(sPerEnfAnt);
				//local
				Percentatge per3 = percentatgeDao.findByIdPenyaITipus(penya.getIdPenya(), LOCAL);
				String sPerLocal = per3.getValor();
				double perLocal = Double.parseDouble(sPerLocal);
				prediccioLocal = prediccioLocal + (perLocal/10);
				//ultims partits Local
				Percentatge per4 = percentatgeDao.findByIdPenyaITipus(penya.getIdPenya(), ULTIMS_RESULTATS);
				String sPerUlPar = per4.getValor();
				double perUlPar = Double.parseDouble(sPerUlPar);
				
				for(Partit p : ultimsPartitsLocal){
					p = partitDao.deproxylock(p);
					if(p.getEquipLocal().getNom().compareTo(sLocal)==0){
						if(p.getGolsLocal() != null){
							if(p.getGolsLocal()>p.getGolsVisitant()){
								prediccioLocal = prediccioLocal + (perUlPar/100);
							}
						}						
					}
				}
				
				for(Partit p : ultimsPartitsVisitant){
					p = partitDao.deproxylock(p);
					if(p.getEquipLocal().getNom().compareTo(sVisitant)==0){
						if(p.getGolsLocal() != null){
							if(p.getGolsLocal()>p.getGolsVisitant()){
								prediccioVisitant = prediccioVisitant + (perUlPar/100);
							}
						}						
					}
				}
				
				String pronRecomanat;
				if(prediccioLocal > prediccioVisitant){
					pronRecomanat = "1 X";
				}else if(prediccioLocal == prediccioVisitant){
					pronRecomanat = "1 X 2";
				}else{
					pronRecomanat = "X 2";
				}
				
														
				ModelMap model = new ModelMap();
				model.addAttribute("equipLocal", equipLocal);
				model.addAttribute("equipVisitant", equipVisitant);
				model.addAttribute("equipEnLligaLocal", equipEnLligaLocal);
				model.addAttribute("equipEnLligaVisitant", equipEnLligaVisitant);
				model.addAttribute("classLocal",classLocal);
				model.addAttribute("classVisitant",classVisitant);
				model.addAttribute("partitsAnteriors",partitsAnteriors);
				model.addAttribute("ultimsPartitsLocal",ultimsPartitsLocal);
				model.addAttribute("ultimsPartitsVisitant",ultimsPartitsVisitant);
				model.addAttribute("pronRecomanat", pronRecomanat);
				return new ModelAndView("usuari/estadisticaEquips", model);
	}

}